/**
* Assignment                P1.java               Due: July 2, 2011 @ 6:00 am
 *
 * login: cs11ubn
 */

import java.util.Scanner;

/**
 *class P1
 * This program takes a grade in the form of a long, then determines and outputs
 * the letter grade using two methods. Method one uses multiple if-else
 * statements, while method two uses a switch statement.
 */
public class P1
{
  public static void main(String[] args)
  {
    // Constant values
   
    // Range
    final int VALID_MIN = 0;
    final int VALID_MAX = 100;    
   
    // Grades
    final int FIRST_DIGIT_A_PP = 10;
    final int FIRST_DIGIT_A = 9;
    final int FIRST_DIGIT_B = 8;
    final int FIRST_DIGIT_C = 7;
    final int FIRST_DIGIT_D = 6;
    // Everything below is an F
   
    // Minus and Plus Ranges
    final int MINUS_MIN = 0;
    final int MINUS_MAX = 2;
    final int PLUS_MIN = 7;
    final int PLUS_MAX = 9;
  
    char choice; // First char of inputStr, if 'n' or 'N', exit program
    long num; // Holds the user input
    String adjective = null; // Holds the adjective for the grade
    int validNum; // Holds the 0-100 value
    int firstDigit; // Holds the first digit of the grade
    int lastDigit; // Holds the last digit of the grade
    String letterGrade = null; // Holds the exact letter grade
    Scanner scan = new Scanner(System.in); // Scanner for input
    String inputStr = null; // Raw input from prompt for continue
                
    // Loops until the user gives a value of 'n' or 'N' when prompted
    do
    {
      // Initialize num to an invalid value. Min - 1 will work
      num = VALID_MIN - 1;

      // Loops until valid number is given
      while( num < VALID_MIN )
      {
        // Put a new line for increased easy-to-read...ness
        System.out.println();
      
        // Prompt for and grab input
        System.out.print("Enter numerical grade:  ");
        num = scan.nextLong();
        
        // Error check for output
        if (num < VALID_MIN)
        {
          System.out.println("ERROR: Enter a positive whole number!");
        }
      }
      
      // Loop through until num is less than 100
      // Do not have to worry about negative numbers as that is
      // considered invalid input and will prompt the user again
      for (; num > VALID_MAX;)
      {
        num /= 10;
      }
      
      // Store the for sure integer sized number into validNum
      validNum = (int) num;
      
      firstDigit = (validNum / 10); // Get the grades first digit
      
      // Example: validNum = 84, firstDigit = 8, lastDigit = 84-(8*10)=4
      lastDigit = validNum - (firstDigit * 10);
      
      // Method 1 using if else
      if (firstDigit == FIRST_DIGIT_A_PP)
      {
        // validNum was 100
        adjective = "Excellent";
        letterGrade = "A++";
      }
      else if (firstDigit == FIRST_DIGIT_A)
      {
        // A
        adjective = "Excellent";
        
        // Find specific the letter grade
        if ((lastDigit >= PLUS_MIN) && (lastDigit <= PLUS_MAX))
        {
          letterGrade = "A+";
        }
        else if ((lastDigit >= MINUS_MIN) && (lastDigit <= MINUS_MAX))
        {
          letterGrade = "A-";
        }
        else
        {
          letterGrade = "A";
        }
      }
      else if (firstDigit == FIRST_DIGIT_B)
      {
        // B
        adjective = "Good";
        
        // Find specific the letter grade
        if ((lastDigit >= PLUS_MIN) && (lastDigit <= PLUS_MAX))
        {
          letterGrade = "B+";
        }
        else if ((lastDigit >= MINUS_MIN) && (lastDigit <= MINUS_MAX))
        {
          letterGrade = "B-";
        }
        else
        {
          letterGrade = "B";
        }
      }
      else if (firstDigit == FIRST_DIGIT_C)
      {
        // C
        adjective = "Average";
        
        // Find specific the letter grade
        if ((lastDigit >= PLUS_MIN) && (lastDigit <= PLUS_MAX))
        {
          letterGrade = "C+";
        }
        else if ((lastDigit >= MINUS_MIN) && (lastDigit <= MINUS_MAX))
        {
          letterGrade = "C-";
        }
        else
        {
          letterGrade = "C";
        }
      }
      else if (firstDigit == FIRST_DIGIT_D)
      {
        // D
        adjective = "Poor";
        
        letterGrade = "D"; // D has no plus or minus
      }
      else
      {
        // F
        adjective = "Failing";
        
        // Don't need to look for plus or minus, always minus minus
        letterGrade = "F--";
      }
      
      // If else output
      System.out.print("Using if else, grade of " + validNum + " is ");
      System.out.println(adjective + " " + letterGrade);
      
      letterGrade = adjective = null; // Reset variables
      
      // Using switch statements
      switch (firstDigit)
      {
        case FIRST_DIGIT_A_PP: // Special case for an A++
          letterGrade = "A++";
          adjective = "Excellent";
          break;
        case FIRST_DIGIT_A: // A
          adjective = "Excellent";
          
          // Find specific the letter grade
          if ((lastDigit >= PLUS_MIN) && (lastDigit <= PLUS_MAX))
          {
            letterGrade = "A+";
          }
          else if ((lastDigit >= MINUS_MIN) && (lastDigit <= MINUS_MAX))
          {
            letterGrade = "A-";
          }
          else
          {
            letterGrade = "A";
          }
          
          break;
        case FIRST_DIGIT_B: // B
          adjective = "Good";
          
          // Find specific the letter grade
          if ((lastDigit >= PLUS_MIN) && (lastDigit <= PLUS_MAX))
          {
            letterGrade = "B+";
          }
          else if ((lastDigit >= MINUS_MIN) && (lastDigit <= MINUS_MAX))
          {
            letterGrade = "B-";
          }
          else
          {
            letterGrade = "B";
          }
          break;
        case FIRST_DIGIT_C: // C
          adjective = "Average";
          
          // Find specific the letter grade
          if ((lastDigit >= PLUS_MIN) && (lastDigit <= PLUS_MAX))
          {
            letterGrade = "C+";
          }
          else if ((lastDigit >= MINUS_MIN) && (lastDigit <= MINUS_MAX))
          {
            letterGrade = "C-";
          }
          else
          {
            letterGrade = "C";
          }
          break;
        case FIRST_DIGIT_D: // D
          adjective = "Poor";
          
          letterGrade = "D"; // No pluses or minuses for D
          break;
        default: // Default case, only an F will get here
          adjective = "Failing";
          
          // Don't need to look for plus or minus, always minus minus
          letterGrade = "F--";
          break;
      }
      
      // Switch output
      System.out.print("Using switch, grade of " + validNum + " is ");
      System.out.println(adjective + " " + letterGrade);
      
      // Prompt for continue
      System.out.print("Want to calculate a grade (y/n)?  ");
      inputStr = scan.next(); // Grab input
      
      choice = inputStr.charAt(0); // Get the first char of the raw inputStr
    } while ((choice != 'n') && (choice != 'N')); // Loop while NOT 'n' nor 'N'
    
    scan.close(); // Close Scanner
    System.exit(0); // Close all connections
  }
}

